const ObsClient = require('esdk-obs-nodejs');
import * as fs from 'fs-extra';
import { CloudServiceInterface, FileInfo, CloudConfig } from '../types';
import { Logger } from '../../utils/Logger';

export class HuaweiCloudService implements CloudServiceInterface {
  private obs: any;
  private config: CloudConfig;

  constructor(config: CloudConfig) {
    this.config = config;
    this.obs = new ObsClient({
      access_key_id: config.accessKeyId,
      secret_access_key: config.secretAccessKey,
      server: config.endpoint || `https://obs.${config.region}.myhuaweicloud.com`
    });
  }

  /**
   * 上传文件
   */
  async uploadFile(
    filePath: string,
    remotePath: string,
    onProgress?: (progress: number) => void
  ): Promise<boolean> {
    try {
      const fileStream = fs.createReadStream(filePath);
      const stat = fs.statSync(filePath);
      
      const params = {
        Bucket: this.config.bucket,
        Key: remotePath,
        Body: fileStream,
        ContentLength: stat.size,
        ProgressCallback: (transferredAmount: number, totalAmount: number) => {
          if (onProgress) {
            const progress = (transferredAmount / totalAmount) * 100;
            onProgress(progress);
          }
        }
      };

      const result = await this.obs.putObject(params);
      
      if (result.CommonMsg.Status < 300) {
        Logger.info('华为云上传成功:', result);
        return true;
      } else {
        Logger.error('华为云上传失败:', result.CommonMsg);
        return false;
      }
    } catch (error) {
      Logger.error('华为云上传异常:', error);
      return false;
    }
  }

  /**
   * 列出文件
   */
  async listFiles(remotePath: string): Promise<FileInfo[]> {
    try {
      Logger.info(`华为云开始列出文件，路径: ${remotePath}`);
      
      const params = {
        Bucket: this.config.bucket,
        Prefix: remotePath || '',
        MaxKeys: 1000
      };

      const result = await this.obs.listObjects(params);
      
      if (result.CommonMsg.Status >= 300) {
        Logger.error('华为云列出文件失败:', result.CommonMsg);
        return [];
      }

      const files: FileInfo[] = [];
      
      if (result.InterfaceResult && result.InterfaceResult.Contents) {
        for (const item of result.InterfaceResult.Contents) {
          files.push({
            key: item.Key,
            size: item.Size,
            lastModified: new Date(item.LastModified),
            etag: item.ETag
          });
        }
      }

      Logger.info(`华为云找到 ${files.length} 个文件`);
      return files;
    } catch (error) {
      Logger.error('华为云列出文件异常:', error);
      return [];
    }
  }

  /**
   * 删除文件
   */
  async deleteFile(remotePath: string): Promise<boolean> {
    try {
      const params = {
        Bucket: this.config.bucket,
        Key: remotePath
      };

      const result = await this.obs.deleteObject(params);
      
      if (result.CommonMsg.Status < 300) {
        Logger.info('华为云删除文件成功:', remotePath);
        return true;
      } else {
        Logger.error('华为云删除文件失败:', result.CommonMsg);
        return false;
      }
    } catch (error) {
      Logger.error('华为云删除文件异常:', error);
      return false;
    }
  }

  /**
   * 测试连接
   */
  async testConnection(): Promise<boolean> {
    try {
      const params = {
        Bucket: this.config.bucket
      };

      const result = await this.obs.headBucket(params);
      
      if (result.CommonMsg.Status < 300) {
        Logger.info('华为云连接测试成功');
        return true;
      } else {
        Logger.error('华为云连接测试失败:', result.CommonMsg);
        return false;
      }
    } catch (error) {
      Logger.error('华为云连接测试异常:', error);
      return false;
    }
  }

  /**
   * 获取文件URL
   */
  getFileUrl(remotePath: string): string {
    const endpoint = this.config.endpoint || `https://obs.${this.config.region}.myhuaweicloud.com`;
    return `${endpoint}/${this.config.bucket}/${remotePath}`;
  }

  /**
   * 检查文件是否存在
   */
  async fileExists(remotePath: string): Promise<boolean> {
    try {
      const params = {
        Bucket: this.config.bucket,
        Key: remotePath
      };

      const result = await this.obs.headObject(params);
      return result.CommonMsg.Status < 300;
    } catch (error) {
      return false;
    }
  }

  /**
   * 获取文件元数据
   */
  async getFileMetadata(remotePath: string): Promise<FileInfo | null> {
    try {
      const params = {
        Bucket: this.config.bucket,
        Key: remotePath
      };

      const result = await this.obs.headObject(params);
      
      if (result.CommonMsg.Status < 300) {
        return {
          key: remotePath,
          size: parseInt(result.InterfaceResult.ContentLength || '0'),
          lastModified: new Date(result.InterfaceResult.LastModified || new Date()),
          etag: result.InterfaceResult.ETag
        };
      }
      
      return null;
    } catch (error) {
      Logger.error('华为云获取文件元数据异常:', error);
      return null;
    }
  }

  /**
   * 获取预签名URL
   */
  async getPresignedUrl(remotePath: string, expires: number = 3600): Promise<string> {
    try {
      const params = {
        Bucket: this.config.bucket,
        Key: remotePath,
        Expires: expires
      };

      const result = await this.obs.createSignedUrlSync({
        Method: 'GET',
        ...params
      });

      return result.SignedUrl || '';
    } catch (error) {
      Logger.error('华为云获取预签名URL异常:', error);
      return '';
    }
  }
}